use clap::Parser;
use std::fs;
use std::io;
mod generators;
mod processor;

/// Arguments provided to the cli program.
#[derive(Parser, Debug, Clone)]
#[clap(about, version, author)]
struct Args {
    /// File to parse
    file: String,

    /// Output file
    #[clap(short, long)]
    output: Option<String>,

    /// Type of generator
    #[clap(arg_enum, short, long)]
    generator: Option<generators::InbuiltGenerators>,
}

impl Args {
    pub fn get_generator(&self) -> Box<dyn generators::Generator> {
        match self.generator {
            Some(generators::InbuiltGenerators::HTML) => Box::new(generators::HtmlGenerator::new()),
            Some(generators::InbuiltGenerators::ANSI) => Box::new(generators::AnsiGenerator::new()),
            None => {
                eprintln!("Using ansi generator as a default!");
                Box::new(generators::AnsiGenerator::new())
            }
        }
    }

    pub fn get_output_file(&self) -> String {
        match self.output.clone() {
            Some(s) => s,
            None => format!("{}.out", self.file),
        }
    }
}

fn main() -> io::Result<()> {
    let args = Args::parse();

    // input and output files
    let in_file = &args.file;
    let out_file = args.get_output_file();

    let tokens = processor::DocToken::from_file(in_file.as_str());

    // gets generator to use
    let mut generator = args.get_generator();
    let out_str = generator.generate(&tokens) + "\n";

    fs::write(out_file, out_str)?;

    Ok(())
}
